package com.itlong.cloud.operate.service.impl;


import com.alibaba.fastjson.JSON;
import com.itlong.cloud.POJO.DTO.operate.OperateAssignmentManageDTO;
import com.itlong.cloud.POJO.PO.*;
import com.itlong.cloud.POJO.VO.operate.*;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.enumerate.DataStatusEnum;
import com.itlong.cloud.enumerate.FeeTypeEnum;
import com.itlong.cloud.operate.dao.IOperateAssignmentManageDao;
import com.itlong.cloud.operate.dao.IOperateBusinessChargeDao;
import com.itlong.cloud.operate.service.IOperateAssignmentManageService;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.random.LogicIdUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * <desc>
 *      任务书管理服务层接口实现类
 *      任务书产品、任务书产品类型、任务书产品型号、产品编码（u8同步来的），几个东西要区分
 * </desc>
 *
 * @createDate 2020/11/30
 **/
@Service
public class OperateAssignmentManageServiceImpl implements IOperateAssignmentManageService {


    public static final Logger log  = LoggerFactory.getLogger(OperateAssignmentManageServiceImpl.class);

    @Autowired
    private IOperateAssignmentManageDao iOperateAssignmentManageDao;

    @Autowired
    private IOperateBusinessChargeDao iOperateBusinessChargeDao;

    @Autowired
    private RedisService redisService;

    //同步任务书线程池
    private static ExecutorService assignmentSyncThreadPool = Executors.newFixedThreadPool(10);

    /**
     * <desc>
     *      获取详情
     * </desc>
     *
     * @param operateAssignmentManageDTO 运营任务书管理DTO
     * @return
     * @Author Zhu.yj
     * @createDate  2020/11/30
     */
    @Override
    public OperateAssignmentDetailVO getDetail(OperateAssignmentManageDTO operateAssignmentManageDTO) throws Exception {

        //组成任务书产品类型
        Set<String> productIdSet = new HashSet<>();
        OperateAssignmentDetailVO operateAssignmentDetailVO = iOperateAssignmentManageDao.getAssignmentDetail(operateAssignmentManageDTO.getAssignmentNumber());
        //未找到任务书信息
        if (operateAssignmentDetailVO == null){
            return null;
        }
        OperateAssignmentInfoVO detailVOList = iOperateAssignmentManageDao.getAssignmentProductList(operateAssignmentManageDTO.getAssignmentNumber());

        //找到任务书产品型号规则列表，根据order正序排序
        List<OperateAssignmentProductVO> assignmentProductList = iOperateAssignmentManageDao.getAssignmentProductModelDetail();

        //获取云服务费收费信息
        List<OperateAssignmentProductVO> cloudServiceList = getAssignmentProductList(operateAssignmentManageDTO.getAssignmentNumber(), productIdSet, assignmentProductList);
        log.info("库存编码大小" + productIdSet.size());

        if (detailVOList != null && detailVOList.getAssignmentDetailList() != null){
            detailVOList.getAssignmentDetailList().forEach(assignmentDetail -> {
                if (productIdSet.contains(assignmentDetail.getProductId())){
                    assignmentDetail.setRedFlag(1);
                }else {
                    assignmentDetail.setRedFlag(0);
                }
            });
        }
        operateAssignmentDetailVO.setAssignmentInfoVO(detailVOList);
        operateAssignmentDetailVO.setCloudServiceCostInfo(cloudServiceList);
        return operateAssignmentDetailVO;
    }

    /**
     * <desc>
     *      分页获取任务书列表
     * </desc>
     *
     * @param operateAssignmentManageDTO 运营任务书管理DTO
     * @return 任务书分页数据
     * @Author Zhu.yj
     * @createDate  2020/12/1
     */
    @Override
    public Page<OperateAssignmentPageVO> getPage(OperateAssignmentManageDTO operateAssignmentManageDTO) throws Exception {
        if (StringUtils.isBlank(operateAssignmentManageDTO.getOrderColumn()) || StringUtils.isBlank(operateAssignmentManageDTO.getOrderRule())){
            operateAssignmentManageDTO.setOrderColumn("orderTime");
            operateAssignmentManageDTO.setOrderRule("DESC");
        }
        Page<OperateAssignmentPageVO> page = new Page<>();
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(operateAssignmentManageDTO);
        page.getPage().setCurrentPage(operateAssignmentManageDTO.getCurrentPage());
        page.getPage().setPageSize(operateAssignmentManageDTO.getPageSize());
        params.put("startSlip", page.getPage().getStartSlip());
        params.put("pageSize", page.getPage().getPageSize());
        //此处单独处理作用于项目管理时的查询逻辑
        if(StringUtils.isNotBlank(operateAssignmentManageDTO.getMark())){
            page.setRows(iOperateAssignmentManageDao.getAssignmentListByProject(params), iOperateAssignmentManageDao.getAssignmentListCountByProject(params));
        }else{
            page.setRows(iOperateAssignmentManageDao.getAssignmentList(params), iOperateAssignmentManageDao.getAssignmentListCount(params));
        }
        return page;
    }

    /**
     * <desc>
     *      创建云服务费首三年订单
     * </desc>
     *
     * @param firstSync 是否是首次同步 1是 0否
     * @Author Zhu.yj
     * @createDate  2020/12/2
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean createCloudServiceCostOrderTimeTask(String firstSync) throws Exception{

        //只自动创建从u8同步来的，且运营平台尚未创建已审批通过的云服务费订单
        List<String> assignmentIdList = iOperateAssignmentManageDao.getAssignmentInfoList(firstSync);
        //若没有符合的任务书，则不需要创建，直接返回
        if (assignmentIdList == null || assignmentIdList.isEmpty()){
            return false;
        }
        this.saveCloudServiceCostInfo(assignmentIdList, null);
        return true;
    }

    /**
     * <desc>
     *      手动同步任务书
     * </desc>
     *
     * @param operateAssignmentManageDTO 运营任务书管理DTO
     * @return
     * @Author Zhu.yj
     * @createDate  2020/12/17
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer assignmentSync(OperateAssignmentManageDTO operateAssignmentManageDTO) throws Exception {
        assignmentSyncThreadPool.execute(() ->{
            try{
                Date nowTime = new Date();
                List<String> assignmentNumber = StringHandlerUtil.splitStringList(operateAssignmentManageDTO.getAssignmentNumber());
                //找出需创建或需修改的收费订单的任务书
                //2021/3/15日添加逻辑，筛选掉发货条件为否的任务书
                List<String> addAssignmentNumberList = iOperateAssignmentManageDao.getAddAssignmentNumberList(assignmentNumber);

                //找出需要删除商务收费订单的任务书
                List<String> deleteAssignmentNumberList
                        = assignmentNumber.stream().filter(item-> !addAssignmentNumberList.contains(item)).collect(Collectors.toList());

                if (!deleteAssignmentNumberList.isEmpty()){
                    //逻辑删除运营保存的任务书订单关系，订单数据，任务书订单
                    List<String> orderIdList = iOperateAssignmentManageDao.getOrderIdByAssignmentNumber(deleteAssignmentNumberList);
                    if (!orderIdList.isEmpty()){
                        iOperateAssignmentManageDao.deleteOrderInfo(orderIdList);
                        iOperateAssignmentManageDao.deleteOrderData(orderIdList);
                        iOperateAssignmentManageDao.deleteAssignmentOrder(orderIdList);
                    }
                }
                this.saveCloudServiceCostInfo(addAssignmentNumberList, operateAssignmentManageDTO.getMyUserName());
                // 保存特殊操作日志
                OperateUserInfoPO operateUserInfoPO = iOperateBusinessChargeDao.getOperateUserPO(operateAssignmentManageDTO.getMyUserName());
                List<OperationSpecialLogPO> list = new ArrayList<>();
                for (String number : assignmentNumber){
                    OperationSpecialLogPO operationSpecialLogPO = new OperationSpecialLogPO();
                    operationSpecialLogPO.setLogId(LogicIdUtil.bussinessId());
                    operationSpecialLogPO.setOuterId(number);
                    operationSpecialLogPO.setAccount(operateUserInfoPO.getUserName());
                    operationSpecialLogPO.setRealName(operateUserInfoPO.getRealName());
                    operationSpecialLogPO.setIp(operateAssignmentManageDTO.getIp());
                    //6为任务书
                    operationSpecialLogPO.setFunctionType(6);
                    operationSpecialLogPO.setOperateFunction("/云服务费/任务书管理");

                    operationSpecialLogPO.setOperateDec(operateUserInfoPO.getRealName() + "执行同步操作");
                    operationSpecialLogPO.setOperateData(JSON.toJSONString(operateAssignmentManageDTO));
                    operationSpecialLogPO.setOperateWay("同步");
                    operationSpecialLogPO.setStatus(DataStatusEnum.NORMAL.getType());
                    operationSpecialLogPO.setCreateTime(nowTime);
                    operationSpecialLogPO.setUpdateTime(nowTime);
                    list.add(operationSpecialLogPO);
                }
                iOperateBusinessChargeDao.batchSaveOperationLogData(list);
            }catch (Exception e){
                log.info("【手动同步任务书信息失败】", e);
                //同步异常之后也删除缓存
                redisService.del(RedisConstant.ASSIGNMENT_SYNC_REDIS_KEY + operateAssignmentManageDTO.getMyUserName());
            }finally {
                redisService.del(RedisConstant.ASSIGNMENT_SYNC_REDIS_KEY + operateAssignmentManageDTO.getMyUserName());
            }
        });

        return 1;
    }

    /**
     * <desc>
     *      根据任务书编号创建首三年云服务费订单
     * </desc>
     *
     * @param
     * @return
     * @Author Zhu.yj
     * @createDate  2020/12/17
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    protected void saveCloudServiceCostInfo(List<String> assignmentIdList, String myUserName)throws Exception{
        List<PropertyCloudServiceAssignmentDataPO> assignmentDataList = new ArrayList<>();
        List<PropertyCloudServiceCostOrderDataPO> serviceCostOrderDataList = new ArrayList<>();
        List<PropertyCloudServiceCostOrderInfoPO> serviceCostOrderInfoList = new ArrayList<>();
        List<Map<String, Object>> serviceCostOrderInfoUpdateList = new ArrayList<>();
        Date nowTime = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat(DateUtil.DATE_FORMAT_TYPE1);
        SimpleDateFormat sdfDay = new SimpleDateFormat(DateUtil.YYYYMMDD);
        SimpleDateFormat sdfSqlDay = new SimpleDateFormat(DateUtil.YMDSQL);
        String nowDay = sdfDay.format(nowTime);
        //找出符合创建云服务费首三年订单的任务书列表
        int currentIndex = 0;
        for (String assignmentId : assignmentIdList){
            currentIndex ++;
            OperateAssignmentDetailVO operateAssignmentDetailVO = iOperateAssignmentManageDao.getAssignmentDetail(assignmentId);

            //获取任务书详细信息
            OperateAssignmentInfoVO assignmentInfoVO = iOperateAssignmentManageDao.getAssignmentProductList(assignmentId);
            //获取任务书下首个自动创建的云服务费订单
            PropertyCloudServiceCostOrderInfoPO costOrderInfoPO = iOperateAssignmentManageDao.getAssignmentOrder(assignmentId);

            //找到任务书产品型号规则列表，根据order正序排序
            List<OperateAssignmentProductVO> assignmentProductList = iOperateAssignmentManageDao.getAssignmentProductModelDetail();

            //获取云服务费收费信息
            List<OperateAssignmentProductVO> assignmentProductVOList = getAssignmentProductList(assignmentId, null, assignmentProductList);

            //若任务书中无收费信息,且尚未创建首三年云服务费订单则直接跳过,并删除已自动创建的云服务费订单、订单数据、任务书订单
            if (assignmentProductVOList == null || assignmentProductVOList.isEmpty()){

                //逻辑删除运营保存的任务书订单关系，订单数据，任务书订单
                List<String> orderIdList = iOperateAssignmentManageDao.getOrderIdByAssignmentNumber(Collections.singletonList(assignmentId));
                if (!orderIdList.isEmpty()){
                    iOperateAssignmentManageDao.deleteOrderInfo(orderIdList);
                    iOperateAssignmentManageDao.deleteOrderData(orderIdList);
                    iOperateAssignmentManageDao.deleteAssignmentOrder(orderIdList);
                }

                continue;
            }
            double totalAmount = 0.0;
            //计算订单总金额
            for (OperateAssignmentProductVO operateAssignmentProductVO : assignmentProductVOList){
                //首3年云服务费
                totalAmount += operateAssignmentProductVO.getFeeNorm() * operateAssignmentProductVO.getEquipCount() * 3;
            }

            String orderId = "";
            //该任务书未创建云服务费订单，则新建
            if (costOrderInfoPO == null || StringUtils.isBlank(costOrderInfoPO.getOrderId())){
                //没有自动创建的云服务费订单，查看该任务书是否有其他云服务费订单，若有，也不创建
                Integer orderCount = iOperateAssignmentManageDao.getAssignmentOrderCount(assignmentId);
                if (orderCount > 0){
                    continue;
                }
                PropertyCloudServiceCostOrderInfoPO cloudServiceCostOrderInfoPO = new PropertyCloudServiceCostOrderInfoPO();
                orderId = LogicIdUtil.bussinessId();
                cloudServiceCostOrderInfoPO.setOrderId(orderId);
                String batchNumber = this.getBatchNumber(orderId, nowDay);
                cloudServiceCostOrderInfoPO.setBatchNumber(batchNumber);
                // 批次号不能超过999
                if (new Long(batchNumber) > new Long(nowDay + "999")) {
                    return;
                }
                //商务审批状态已审批
                cloudServiceCostOrderInfoPO.setBusinessAuditStatus(3);
                cloudServiceCostOrderInfoPO.setProjectId(operateAssignmentDetailVO.getProjectId());
                cloudServiceCostOrderInfoPO.setPaidAmount(new BigDecimal(totalAmount));
                cloudServiceCostOrderInfoPO.setNextAmount(new BigDecimal(totalAmount));
                cloudServiceCostOrderInfoPO.setEndTime(sdfSqlDay.parse(operateAssignmentDetailVO.getEndTime()));
                //默认财务已审批通过
                cloudServiceCostOrderInfoPO.setFeeStatus(2);
                //赠送服务费
                cloudServiceCostOrderInfoPO.setPresented(1);
                cloudServiceCostOrderInfoPO.setStatus(DataStatusEnum.NORMAL.getType());
                cloudServiceCostOrderInfoPO.setCreateTime(nowTime);
                cloudServiceCostOrderInfoPO.setUpdateTime(nowTime);
                cloudServiceCostOrderInfoPO.setAutoCreatePresent(1);
                cloudServiceCostOrderInfoPO.setAcceptStatus(3);
                cloudServiceCostOrderInfoPO.setBillingStatus(1);
                serviceCostOrderInfoList.add(cloudServiceCostOrderInfoPO);
            }else {
                orderId = costOrderInfoPO.getOrderId();
                //该任务书已有云服务费订单，则更新
                costOrderInfoPO.setProjectId(operateAssignmentDetailVO.getProjectId());
                costOrderInfoPO.setPaidAmount(new BigDecimal(totalAmount));
                costOrderInfoPO.setNextAmount(new BigDecimal(totalAmount));
                costOrderInfoPO.setEndTime(sdfSqlDay.parse(operateAssignmentDetailVO.getEndTime()));
                costOrderInfoPO.setUpdateTime(nowTime);
                serviceCostOrderInfoUpdateList.add(SqlUtil.durableData(costOrderInfoPO, PlatformConstants.TABLE_UPDATE));

                //干掉该订单数据及任务书与订单关联信息，底下重新创建
                List<String> orderIdList = new ArrayList<>();
                orderIdList.add(costOrderInfoPO.getOrderId());
                iOperateAssignmentManageDao.deleteOrderData(orderIdList);
                iOperateAssignmentManageDao.deleteAssignmentOrder(orderIdList);
            }

            //创建云服务费收费订单数据
            for (OperateAssignmentProductVO operateAssignmentProductVO : assignmentProductVOList){
                PropertyCloudServiceCostOrderDataPO cloudServiceCostOrderDataPO = new PropertyCloudServiceCostOrderDataPO();
                cloudServiceCostOrderDataPO.setDataId(LogicIdUtil.bussinessId());
                cloudServiceCostOrderDataPO.setOrderId(orderId);
                cloudServiceCostOrderDataPO.setAssignmentNumber(assignmentInfoVO.getAssignmentNumber());
                cloudServiceCostOrderDataPO.setProjectId(operateAssignmentDetailVO.getProjectId());
                cloudServiceCostOrderDataPO.setProductType(operateAssignmentProductVO.getProductType());
                cloudServiceCostOrderDataPO.setProduct(operateAssignmentProductVO.getProductName());
                cloudServiceCostOrderDataPO.setFeeNorm(new BigDecimal(operateAssignmentProductVO.getFeeNorm()));
                cloudServiceCostOrderDataPO.setFeeUnit("年");
                cloudServiceCostOrderDataPO.setEquipUnit(FeeTypeEnum.getEquipUnitByType(operateAssignmentProductVO.getProductType()));
                cloudServiceCostOrderDataPO.setEquipCount(operateAssignmentProductVO.getEquipCount());
                cloudServiceCostOrderDataPO.setStartTime(sdfSqlDay.parse(operateAssignmentDetailVO.getDeliveryDate()));
                cloudServiceCostOrderDataPO.setEndTime(sdfSqlDay.parse(operateAssignmentDetailVO.getEndTime()));
                cloudServiceCostOrderDataPO.setCreateTime(nowTime);
                cloudServiceCostOrderDataPO.setUpdateTime(nowTime);
                cloudServiceCostOrderDataPO.setStatus(DataStatusEnum.NORMAL.getType());
                cloudServiceCostOrderDataPO.setCreateUserId("autocreate");
                cloudServiceCostOrderDataPO.setOperateUserId("autocreate");
                serviceCostOrderDataList.add(cloudServiceCostOrderDataPO);
            }

            //创建任务书信息表
            PropertyCloudServiceAssignmentDataPO cloudServiceAssignmentDataPO = new PropertyCloudServiceAssignmentDataPO();
            cloudServiceAssignmentDataPO.setAssignmentId(LogicIdUtil.bussinessId());
            cloudServiceAssignmentDataPO.setOrderId(orderId);
            cloudServiceAssignmentDataPO.setAssignmentNumber(assignmentInfoVO.getAssignmentNumber());
            cloudServiceAssignmentDataPO.setProjectId(operateAssignmentDetailVO.getProjectId());
            cloudServiceAssignmentDataPO.setDepartment(assignmentInfoVO.getDepartmentName());
            cloudServiceAssignmentDataPO.setSalesmen(assignmentInfoVO.getSaleName());
            cloudServiceAssignmentDataPO.setCustomerName(assignmentInfoVO.getCustomerName());
            cloudServiceAssignmentDataPO.setDownTime(sdfSqlDay.parse(assignmentInfoVO.getAssignmentDate()));
            cloudServiceAssignmentDataPO.setCreateTime(nowTime);
            cloudServiceAssignmentDataPO.setUpdateTime(nowTime);
            cloudServiceAssignmentDataPO.setStatus(DataStatusEnum.NORMAL.getType());
            cloudServiceAssignmentDataPO.setCreateUserId("autocreate");
            cloudServiceAssignmentDataPO.setOperateUserId("autocreate");
            assignmentDataList.add(cloudServiceAssignmentDataPO);


            if (myUserName != null){
                double currentPercent = currentIndex/ (double)assignmentIdList.size();
                redisService.set(RedisConstant.ASSIGNMENT_SYNC_REDIS_KEY + myUserName, Double.toString(currentPercent));
            }
        }

        if (!assignmentDataList.isEmpty()){
            //保存任务书、订单、订单数据
            iOperateBusinessChargeDao.batchSaveAssignmentData(assignmentDataList);
        }
        if (!serviceCostOrderDataList.isEmpty()){
            //找出任务书中云服务费收费明细,创建云服务费收费明细信息
            iOperateBusinessChargeDao.batchSaveOrderData(serviceCostOrderDataList);
        }
        if (!serviceCostOrderInfoList.isEmpty()){
            //创建云服务费订单信息
            iOperateBusinessChargeDao.batchSaveOrderInfo(serviceCostOrderInfoList);
        }
        if (!serviceCostOrderInfoUpdateList.isEmpty()){
            //批量修改云服务费订单信息
            iOperateBusinessChargeDao.batchUpdateOrderInfo(serviceCostOrderInfoUpdateList);
        }
    }

    /**
     * <desc>
     *      根据任务书中产品编码自动匹配获取任务书产品类别
     * </desc>
     *
     * @param assignmentNumber 任务书编码
     * @param productIdList 组成任务书产品类型的产品id列表
     * @return
     * @Author Zhu.yj
     * @createDate  2020/12/2
     */
    private List<OperateAssignmentProductVO> getAssignmentProductList(String assignmentNumber, Set<String> productIdList, List<OperateAssignmentProductVO> assignmentProductList) throws Exception{
        //产品型号列表
        Map<String, Integer> assignmentProductMap = new HashMap<>();
        List<OperateAssignmentProductVO> assignmentProductReturnList = new ArrayList<>();
        Set<String> productModelIdList = new HashSet<>();
        //找到任务书中的各产品的产品型号的数量
        List<OperateModelCodeVO> assignmentProductsCountList = iOperateAssignmentManageDao.getAssignmentProductsCount(assignmentNumber);

        if (assignmentProductsCountList == null){
            return null;
        }

        //将list->map中的productId及totalCount重组成新的map，key:value->productId:totalCount
        for (OperateModelCodeVO codeVO : assignmentProductsCountList){
            Integer totalCount = codeVO.getTotalCount();
            assignmentProductMap.put(codeVO.getModelId(), totalCount);
        }

        /**
            遍历任务书中的产品编码信息，根据规则（新建任务书产品型号时创建的）通过产品编码找出匹配的任务书产品型号，再根据
            任务书产品类型的规则找出对应的任务书产品
         */
        for (OperateAssignmentProductVO assignmentProductVO : assignmentProductList){
            OperateAssignmentProductVO productVO = new OperateAssignmentProductVO();
            //产品型号
            for (OperateAssignmentProductModelRelationVO relationVO : assignmentProductVO.getProductModelList()){
                //只计算开启数量计算的产品型号
                if (1 != relationVO.getCalculateAmount() || relationVO.getModelId() == null){
                    continue;
                }
                Map<String, Integer> productModelMap = new HashMap<>();
                List<String> modelIdList = StringHandlerUtil.splitStringList(relationVO.getModelId());
                for (String modelId : modelIdList){
                    if (assignmentProductMap.get(modelId) != null && assignmentProductMap.get(modelId) != 0){
                        productModelMap.put(modelId, assignmentProductMap.get(modelId));
                    }
                }
                if (productModelMap.entrySet().size() == modelIdList.size()){
                    //找到productCodeMap中count最小值，以最小值为准
                    int min = getMinValue(productModelMap);
                    //用count*计算倍率 即为数量，则此relationVO计算完成
                    int count = min * relationVO.getCalculateTimes();
                    productVO.setProductType(assignmentProductVO.getProductType());
                    productVO.setFeeNorm(assignmentProductVO.getFeeNorm());
                    productVO.setProductName(assignmentProductVO.getProductName());
                    productVO.setEquipCount(productVO.getEquipCount() + count);
                    productModelIdList.addAll(productModelMap.keySet());
                    //产品型号总数量 减去已计算的产品型号
                    for (String key : productModelMap.keySet()){
                        int currentCount = assignmentProductMap.get(key);
                        assignmentProductMap.put(key, currentCount - min);
                    }
                }
            }
            if (StringUtils.isNotBlank(productVO.getProductName())){
                assignmentProductReturnList.add(productVO);
            }
        }


        //产品新增需求，若产品编码是组成云服务费的收费项，则标红
        if (productIdList != null){
            for (OperateModelCodeVO codeVO : assignmentProductsCountList){
                if (productModelIdList.contains(codeVO.getModelId())){
                    productIdList.addAll(StringHandlerUtil.splitStringList(codeVO.getProductId()));
                }
            }
        }
        return assignmentProductReturnList;
    }

    /**
     * <desc>
     *      获取批次号，规避并发获取同个情况，因为分布式，服务部署多台服务器，只有synchronized关键字达不到效果
     * </desc>
     *
     * @return 批次号
     * @author wangzhi
     * @createDate 2019/12/11
     */
     private synchronized String getBatchNumber(String userId, String nowDay){
        String markId = LogicIdUtil.bussinessId();
        String key = RedisConstant.OPERATE_BUSINESS_CHARGE_BATCH_NUMBER_KEY + nowDay;
        Long time = RedisConstant.OPERATE_BUSINESS_CHARGE_BATCH_NUMBER_TIME;
        // 获取当日最小可用批次号
        String batchNumber = redisService.get(key);
        if (StringUtils.isBlank(batchNumber) || !this.getLongValue(batchNumber, -1L).equals(-1L)) {
            // 拿到正常的之后赶紧先放一个唯一标志的进去，尽可能规避并发情况
            redisService.set(key, time, markId + "_" + userId);
        } else {
            // 缓存中拿到的批次号不为空且转Long失败，则此时有人正在获取批次号，递归
            return getBatchNumber(userId, nowDay);
        }
        if (StringUtils.isBlank(batchNumber)) {
            // 缓存中还没有今天批次号或规避缓存数据丢失情况，从数据库中先获取当日最大批次号
            String batchNumberData = iOperateBusinessChargeDao.getMaxBatchNumberNowDay(nowDay);
            if (StringUtils.isBlank(batchNumberData)) {
                // 数据库中没有，则当天第一次开始
                batchNumber = nowDay + "001";
                String markValue = redisService.get(key);
                // 获取的值与一开始放入的唯一标志相等，则完成此次获取，并设置下次可用的批次号
                if ((markId + "_" + userId).equals(markValue)) {
                    redisService.set(key, time, new Long(batchNumber) + 1 + "");
                    return batchNumber;
                } else {
                    // 失败了之后再重新拿
                    return getBatchNumber(userId, nowDay);
                }
            } else {
                // 数据库中有，则从最大批次号+1开始
                batchNumber = new Long(batchNumberData) + 1 + "";
                String markValue = redisService.get(key);
                // 获取的值与一开始放入的唯一标志相等，则完成此次获取，并设置下次可用的批次号
                if ((markId + "_" + userId).equals(markValue)) {
                    redisService.set(key, time, new Long(batchNumber) + 1 + "");
                    return batchNumber;
                } else {
                    // 失败了之后再重新拿
                    return getBatchNumber(userId, nowDay);
                }
            }
        } else {
            // 缓存中已经有今天的批次号
            String markValue = redisService.get(key);
            // 获取的值与一开始放入的唯一标志相等，则完成此次获取，并设置下次可用的批次号
            if ((markId + "_" + userId).equals(markValue)) {
                redisService.set(key, time, new Long(batchNumber) + 1 + "");
                return batchNumber;
            } else {
                // 失败了之后再重新拿
                return getBatchNumber(userId, nowDay);
            }
        }
    }

    /**
     * <desc>
     *      String转Long，异常返回默认值
     * </desc>
     *
     * @return 批次号
     * @author wangzhi
     * @createDate 2019/12/11
     */
    private Long getLongValue(String str, Long defaultValue) {
        try {
            return new Long(str);
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * <desc>
     *      获取map中Value的最小值
     * </desc>
     *
     * @param productCodeMap
     * @return
     * @Author Zhu.yj
     * @createDate  2020/12/2
     */
    private Integer getMinValue(Map<String, Integer> productCodeMap) throws Exception{

        Collection<Integer> codeMap = productCodeMap.values();
        Object[] valueArr = codeMap.toArray();
        Arrays.sort(valueArr);
        return (int) valueArr[0];
    }
}
